package graph.editor.enhanced;

import exception.InitialStateException;
import graph.editor.Edge;
import graph.editor.Vertex;

import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.RectangularShape;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import automaton.TypeState;
/**
 * @opt nodefillcolor green
 * @opt attributes
 * @opt operations
 * @depend - - - graph.editor.Edge
 * @depend - - - exception.InitialStateException
 */
public class GraphComponentModified extends graph.editor.GraphComponent{

	private static final long serialVersionUID = 1L;
	
	private TypeState currentState;
	
	public GraphComponentModified(){
		super();
		this.currentState = TypeState.INTERMEDIATE;
	}
	
	public GraphComponentModified(List<Vertex> vertices, List<Edge> edges){
		this();
		this.vertices 	= vertices;
		this.edges 		= edges;
	}

	public void setVertexSample(RectangularShape sample, TypeState state) {
		setVertexSample(sample);
		currentState = state;
	}

	private Vertex createVertex(int x, int y) {
		RectangularShape rs = newVertexShape(x, y);
		VertexModified v = new VertexModified(rs, Integer.toString(n++), currentState);
		vertices.add(v);
		return v;
	}

	private EdgeModified startEdge(VertexModified v) {
		RectangularShape rs2 = newVertexShape(0, 0);
		RectangularShape rs = v.shape;
		rs2.setFrameFromCenter((int) rs.getCenterX(), (int) rs.getCenterY(),
				(int) rs.getCenterX(), (int) rs.getCenterY());
		EdgeModified l = new EdgeModified(v, new VertexModified(rs2, null, currentState));
		edges.add(l);
		return l;
	}

	public void mousePressed(MouseEvent e) {
		requestFocusInWindow();
		try{
		if ((e.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) == InputEvent.BUTTON3_DOWN_MASK)
			return;
		int 	x 				= e.getX();
		int 	y 				= e.getY();
		Vertex 	v 				= getVertex(x, y);
		Vertex 	initialVertex 	= getInitialVertex();
		if (v == null) {
			currentJointPoint = getJointPoint(x, y);
		}
		if (v == null && currentJointPoint == null){
			if((currentState == TypeState.INITIAL || currentState == TypeState.INITIAL_AND_FINAL) && initialVertex != null)
				throw new InitialStateException(initialVertex, v);
			else
				v = createVertex(x, y);
		}
		if (v != null && e.isShiftDown()){
			if((currentState == TypeState.INITIAL || currentState == TypeState.INITIAL_AND_FINAL) && initialVertex != null)
				throw new InitialStateException(initialVertex, v);
			else
				currentEdge = startEdge((VertexModified)v);
		}
		else
			currentVertex = v;
		}catch(InitialStateException exception){
			exception.printStackTrace();
		}
		repaint();
	}
	
	public VertexModified getInitialVertex(){
		VertexModified initialVertex	= null;
		boolean isSearching 	= true;
		Iterator<Vertex> iterator = vertices.iterator();
		while(isSearching && iterator.hasNext()){
			VertexModified vertex = (VertexModified) iterator.next();
			if(vertex.getState() == TypeState.INITIAL || vertex.getState() == TypeState.INITIAL_AND_FINAL){
				isSearching 	= false;
				initialVertex	= vertex;
			}
		}
		return initialVertex;
	}

	public List<EdgeModified> getEdges() {
		List<EdgeModified> edgesModified = new ArrayList<EdgeModified>();
		for(Edge edge : edges)
			edgesModified.add((EdgeModified) edge);
		return edgesModified;
	}

	public void setEdges(List<EdgeModified> edges){
		int index = 0;
		for(EdgeModified edge : edges)
			this.edges.add(index, edge);
	}
	
	public List<VertexModified> getVertices() {
		List<VertexModified> verticesModified =  new ArrayList<VertexModified>();
		for(Vertex vertex : vertices)
			verticesModified.add((VertexModified) vertex);
		return verticesModified;
	}
	
	public void setVertices(List<VertexModified> vertices) {
		int index = 0;
		for(VertexModified vertex : vertices)
			this.vertices.add(index, vertex);
	}
	
	public void refresh(){
		repaint();
	}

	public void addTextField() {
		for(Edge edge: edges){
			this.add(edge.textField);
		}
		
	}
}
